package cn.szsys.integration.helper.business.impl;

import cn.szsys.integration.billrule.BillingMapperUtils;
import cn.szsys.integration.billrule.annoation.BillRule;
import cn.szsys.integration.billrule.entity.BillingInfo;
import cn.szsys.integration.constants.BillRuleRecordTypeEnum;
import cn.szsys.integration.constants.TqszEdcationVerifyMapperedEnum;
import cn.szsys.integration.dto.EducationVerifyDTO;
import cn.szsys.integration.ex.BusinessException;
import cn.szsys.integration.ex.enums.ExceptionEnum;
import cn.szsys.integration.helper.BusinessBeanNameConstant;
import cn.szsys.integration.helper.business.AbstractEducationVerifyHandlerChain;
import cn.szsys.integration.util.OkHttpUtil;
import cn.szsys.integration.util.R;
import cn.szsys.integration.util.RSAUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 学籍校验(E1.0)
 *
 * @author Ryan
 * @since 2025-05-09
 **/
@Component(BusinessBeanNameConstant.EducationVerify.TQSZ_EDUCATION_VERIFY_HANDLER_CHAIN)
@Slf4j
public class TqszEducationVerifyHandlerChain extends AbstractEducationVerifyHandlerChain {
    private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    @Value("${edcation.verify.tqsz.url}")
    private String url;
    @Value("${edcation.verify.tqsz.app-id}")
    private String appId;
    @Value("${edcation.verify.tqsz.secret-key}")
    private String secretKey;
    @Value("${edcation.verify.tqsz.private-key}")
    private String privateKey;

    private String signStr;

    @PostConstruct
    public void init() {
        signStr = "appId="
                .concat(appId)
                .concat("&")
                .concat("appSecret=")
                .concat(secretKey)
                .concat("&")
                .concat("bizData=%s")
                .concat("&")
                .concat("timestamp=%s");
    }

    /**
     * 转换对应结果并设置计费信息
     *
     * @param obj           obj
     * @param consumingTime consumingTime
     * @return {@link R}
     * @author Ryan
     */
    @Override
    public R<?> convertResultAndBilling(JSONObject obj, long consumingTime) {
        String code = obj.getString("code");
        TqszEdcationVerifyMapperedEnum byUpstreamCode = TqszEdcationVerifyMapperedEnum.getByUpstreamCode(code);
        //设置计费数据
        BillingInfo billingInfo = BillingInfo.build(byUpstreamCode.getDownstreamCode(), code, consumingTime);
        BillingMapperUtils.set(billingInfo);

        JSONObject data = new JSONObject();
        data.put("verifyResult", byUpstreamCode.getDownstreamCode());
        return R.success(data, byUpstreamCode.getBilling());
    }

    /**
     * 执行业务处理
     *
     * @param dto          参数
     * @param reqStartTime reqStartTime
     * @return {@link R}
     * @author Ryan
     */
    @Override
    @BillRule(upstream = "tianqushuzi", billRuleRecordType = BillRuleRecordTypeEnum.DAY, product = "教学标签模型(青年版)A1.0")
    public R<?> doHandle(EducationVerifyDTO dto, long reqStartTime) {
        String bodyRaw = "{\n" +
                "    \"custCertNo\": \"" + dto.getIdCard() + "\",\n" +
                "    \"custName\": \"" + dto.getName() + "\",\n" +
                "    \"phone\": \"" + dto.getMobile() + "\"\n" +
                "}";
        String timestamp = LocalDateTime.now().format(DATE_TIME_FORMAT);
        Map<String, String> header = generateHeader(bodyRaw, timestamp);
        log.info("请求TQSZ学籍核验[请求],header :{}, body :{}", header, bodyRaw);

        long startTime = System.currentTimeMillis();
        OkHttpUtil.OkhttpResponse response = OkHttpUtil.builder()
                .addHeaders(header)
                .url(url)
                .post(bodyRaw)
                .sync();
        long endTime = System.currentTimeMillis();
        log.info("请求TQSZ学籍核验[响应], response: {}, 请求耗时: {}ms", response.getData(), (endTime - startTime));
        if (response.getSuccess()) {
            String data = response.getData();
            JSONObject obj = JSON.parseObject(data);
            return convertResultAndBilling(obj, endTime - reqStartTime);
        }
        throw new BusinessException(ExceptionEnum.OP_FAIL, "请求出错!");
    }

    /**
     * 生成header
     *
     * @param body      body
     * @param timestamp timestamp
     * @return {@link Map< String, String>}
     * @author Ryan
     */
    private Map<String, String> generateHeader(String body, String timestamp) {
        Map<String, String> header = new HashMap<>();
        header.put("appId", appId);
        header.put("timestamp", timestamp);
        header.put("sign", generateSign(body, timestamp));
        return header;
    }

    /**
     * 生成签名
     *
     * @param body      body
     * @param timestamp timestamp
     * @return {@link String}
     * @author Ryan
     */
    private String generateSign(String body, String timestamp) {
        String originSignStr = String.format(signStr, body, timestamp);
        try {
            return RSAUtil.sign(originSignStr, privateKey);
        } catch (Exception e) {
            throw new RuntimeException("加签异常");
        }
    }
}
